package service;

import com.alibaba.fastjson.JSON;
import com.baidu.aip.ocr.AipOcr;
import com.thoughtworks.xstream.XStream;
import entity.*;
import entity.res.*;
import lombok.extern.slf4j.Slf4j;
import manager.TemplateMessage;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.LoggerFactory;
import redis.JedisConnectPool;
import redis.clients.jedis.Jedis;
import service.api.ai.AiService;
import service.api.ai.ERNIE_ViLG;
import util.Request;
import util.XmlOrJson;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;


@Slf4j
public class WxServiceImpl {
    static JedisConnectPool jedisPool=new JedisConnectPool();
    static Jedis jedis=jedisPool.getJedis();
    static InputStream in= WxServiceImpl.class.getClassLoader().getResourceAsStream("wx-config.xml");
    static Map<String,String> Xmlmap= WxServiceImpl.parseRequest(in);
    //微信
    private static final String APPID=Xmlmap.get("appid");
    private static final String SECRT=Xmlmap.get("secrt");
    private static final String GET_TOKEN_URL=Xmlmap.get("getToken");
    private static final String GET_USER_INFO=Xmlmap.get("getUserInfo");
    //百度接口
    private static final String APP_ID = Xmlmap.get("baiduID");
    private static final String API_KEY = Xmlmap.get("baiduKey");
    private static final String SECRET_KEY = Xmlmap.get("baiduSecret");
    //微信ai
    private static final String AI_APPID=Xmlmap.get("aiAppid");
    private static final String AI_TOKEN=Xmlmap.get("aiToken");
    private static final String AI_KEY=Xmlmap.get("aiKey");
    private static final String AI_SIGN_URL=Xmlmap.get("aiSignUrl");
    private static final String AI_BOT_URL=Xmlmap.get("aiBotUrl");
    static ERNIE_ViLG ernie_viLG=new ERNIE_ViLG();


    //getToken
    private static AccessToken at;
    private static Signature st;
    private static void getToken(){
        String url=GET_TOKEN_URL.replace("APPID",APPID).replace("APPSECRET",SECRT);
        String tokenstr= Request.get(url);
        JSONObject jsonObject=new JSONObject(tokenstr);
        String token=jsonObject.getString("access_token");
        int expires=jsonObject.getInt("expires_in");
//        String errcode=jsonObject.getString("errcode");
        at=new AccessToken(token,expires);
    }
    private static void getAiToken(){
        String url =AI_SIGN_URL.replace("{TOKEN}",AI_TOKEN);
        Map<String,String> map=new HashMap<>();
        map.put("userid","Golxen");
        String tokenstr= Request.sendPost(url,map);
        JSONObject jsonObject=new JSONObject(tokenstr);
        String signature=jsonObject.getString("signature");
        int expires=jsonObject.getInt("expiresIn");
        st=new Signature(signature,expires);
    }
    public static String getSignature(){
        if (st==null||st.isExpires()){
            getAiToken();
        }
        return st.getSignature();
    }
    public static String getAccessToken(){
        if(at==null||at.isExpires()){
            getToken();
        }
//        if (at.getToken()==null||at.getToken().equals(""))
//            return at.getErrcode();
//        else
            return at.getToken();
    }

    //将获取的请求转换成map
    public static Map parseRequest(InputStream is){

        Map map=new HashMap<>();
        StringBuilder str = new StringBuilder();
        //读取字节流默认似乎不是utf-8，所以转一下
        InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);
        BufferedReader r = new BufferedReader(isr);
        String line=null;
        while (true) {
            try {
                if ((line = r.readLine()) == null) break;
            } catch (IOException e) {
                e.printStackTrace();
            }
            str.append(line);
        }

        if (XmlOrJson.getType(str.toString()).equals("Json")){
            try {
                map = JSON.parseObject(str.toString(),Map.class);
            }catch (Exception e){
                Map<Integer,Map<String,Object>> arraysMap=new HashMap<>();
                List<String> objectList= com.alibaba.fastjson.JSONObject.parseArray(str.toString(),String.class);
                Integer i=0;
                for (String obj:objectList){
                    arraysMap.put(i, com.alibaba.fastjson.JSONObject.parseObject(obj,Map.class));
                    i++;
                }
                map=arraysMap;
            }

        }
        else{
//            SAXReader reader =new SAXReader();
            try {
                //读取输入流，获取文档对象
//                Document document=reader.read(is);
                Document document= DocumentHelper.parseText(str.toString());
                //根据文档对象获取根节点
                Element root=document.getRootElement();
                //获取根节点所有子节点
                List<Element> elements=root.elements();
                for (Element e:elements) {
                    map.put(e.getName(),e.getStringValue());
                }
            } catch (DocumentException e) {
                e.printStackTrace();
            }
        }
        return map;
    }

    //判断请求的消息类型
    public static String getRespose(Map map){
        BaseMessage msg=null;
        String msgType= (String) map.get("MsgType");
        if (msgType==null)
            msgType=new String("rsms");
        switch (msgType){
            case "text":
                msg=dealtextMessage((Map<String,String>)map);
                break;
            case "image":
                msg=dealImageMessage((Map<String,String>)map);
                break;
            case "voice":
                msg=dealvoiceMessage((Map<String,String>)map);
                break;
            case "video":
                msg=dealvideoMessage((Map<String,String>)map);
                break;
            case "music":
                msg=dealmusicMessage((Map<String,String>)map);
                break;
            case "news":
                msg=dealnewsMessage((Map<String,String>)map);
                break;
            case "event":
                msg=dealEvent((Map<String,String>)map);
                break;
            case "TemplateMessage":
                log.info("有走到TM  :"+map);
                TemplateMessage tm=new TemplateMessage();
                tm.sendTemplateMessage((Map<String,String>)map);
                break;
            case "rsms":
                log.info("门店管理系统消息处理");
                TemplateMessage tm2=new TemplateMessage();
                tm2.sendRsmsTemplateMessage((Map<Integer,Map<String,Object>>) map);

        }
        if (msg!=null)
            return beanToXml(msg);
        else
            return "success";
    }

    //xml转换
    private static String beanToXml(BaseMessage msg){
        XStream stream=new XStream();
        stream.processAnnotations(TextMessage.class);
        stream.processAnnotations(ImageMessage.class);
        stream.processAnnotations(MusicMessage.class);
        stream.processAnnotations(NewsMessage.class);
        stream.processAnnotations(VideoMessage.class);
        stream.processAnnotations(VoiceMessage.class);
        return stream.toXML(msg);
    }

    //接收text
    private static BaseMessage dealtextMessage(Map<String,String> map){
        String msg=map.get("Content").replace("\"","\\\"").replace("\n","\\n");
        String openId=map.get("FromUserName");
        BaseMessage tm = null;
        String redisOpenId=jedis.get(openId);
        if (redisOpenId!=null){
            try {
                if (msg.equals("取消")){
                    tm=new TextMessage(map,"已取消");
                    jedis.del(openId);
                }else {
                    boolean isMember=jedis.sismember("openId_set",openId);
                    //文心绘图
//                    String taskId=ernie_viLG.getTaskId(msg);
//                    if (taskId!=null&&!taskId.equals("0")&&!isMember){
//                        tm=new TextMessage(map,"提交成功，请稍后...");
//                        jedis.del(openId);
//                        log.info("获得taskId，准备放入队列---"+openId+":"+taskId);
//                        jedis.publish("task_que",openId+":"+taskId);
//                        jedis.sadd("openId_set",openId);

//                    } else if (isMember){
//                        tm=new TextMessage(map,"提交失败，你还有提交的任务未完成，请等待");
//                        jedis.del(openId);
//                    } else {
//                        tm=new TextMessage(map,"提交失败，请重试");
//                        jedis.del(openId);
//                    }
                    if (isMember){
                        tm=new TextMessage(map,"提交失败，你还有提交的任务未完成，请等待");
                        jedis.del(openId);
                    }else {
                        log.info("获得taskId，准备放入队列---"+openId+":"+msg);
                        jedis.publish("task_que",openId+":"+msg);
//                        long wait = jedis.scard("openId_set");
//                        long exp=wait+System.currentTimeMillis();
//                        jedis.sadd("openId_set",openId+":"+exp);
                        jedis.sadd("openId_set",openId);
                        tm=new TextMessage(map,"提交成功，请稍后...");
                        jedis.del(openId);
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
                tm=new TextMessage(map,"提交失败，请重试,注意敏感词汇");
                jedis.del(openId);
            }


        }else {
            switch (msg) {
//                case "讲笑话":
//                    String apiresq = Request.joke();
//                    JSONObject jsonObject = new JSONObject(apiresq);
//                    String resp = jsonObject.getJSONArray("result").getJSONObject(0).getString("content");
//                    tm = new TextMessage(map, resp);
//                    break;
                case "乡村便民系统":
                    List<Articles> articles = new ArrayList<>();
                    articles.add(new Articles("Golxen个人博客", "点击进入系统", "https://golxen.cn/image/0c47d355621d442d9c66c6f0232b0f81.jpg", "blog.golxen.cn"));
                    tm = new NewsMessage(map, articles);
                    break;
                case "token":
                    tm = new TextMessage(map, getAccessToken());
                    break;
                case "【收到不支持的消息类型，暂无法显示】":
                    tm = new TextMessage(map, "暂时无法支持此消息类型的处理哦！");
                    break;
                default:
                    jedis.publish("task_que2",openId+":"+msg);
            }
        }

//
//        else
//        {
//            String url=AI_BOT_URL.replace("{TOKEN}",AI_TOKEN);
//            Map<String,String> aiBotMap=new HashMap<>();
//            aiBotMap.put("signature",getSignature());
//            aiBotMap.put("query",msg);
//            String answer=API.sendPost(url,aiBotMap);
//            JSONObject jsonObject=new JSONObject(answer);
//            if (jsonObject.getString("answer")==null||jsonObject.getString("answer").equals(""))
//                tm=new TextMessage(map,"我不知道，滚！");
//            else
//                tm=new TextMessage(map,"");
//            return tm;
//        }
        return tm;
    }

    private static BaseMessage dealImageMessage(Map<String,String> map){
        AipOcr client = new AipOcr(APP_ID, API_KEY, SECRET_KEY);

        // 可选：设置网络连接参数
        client.setConnectionTimeoutInMillis(2000);
        client.setSocketTimeoutInMillis(60000);

        // 调用接口
        String path = map.get("PicUrl");
        JSONObject res = client.basicGeneralUrl(path, new HashMap<String, String>());
        JSONArray jsonArray=res.getJSONArray("words_result");
        Iterator<Object> iterator=jsonArray.iterator();
        StringBuilder sb=new StringBuilder();
        while (iterator.hasNext()){
            JSONObject jsonObject= (JSONObject) iterator.next();
            sb.append(jsonObject.getString("words")+"\n");
        }
        if (sb.toString().equals("")||sb.toString()==null)
            return null;
        else
            return new TextMessage(map,sb.toString());
    }
    private static BaseMessage dealvoiceMessage(Map<String,String> map){
        return null;
    }
    private static BaseMessage dealvideoMessage(Map<String,String> map){
        return null;
    }
    private static BaseMessage dealmusicMessage(Map<String,String> map){
        return null;
    }
    private static BaseMessage dealnewsMessage(Map<String,String> map){
        return null;
    }

    //接收事件
    private static BaseMessage dealEvent(Map<String, String> map) {
        String event=map.get("Event");
        switch (event){
            case "CLICK":
                return dealClick(map);
            case "VIEW":
                break;
//            case "pic_photo_or_album":
//                return dealimageMessage(map);
        }
        return null;
    }

    //菜单点击处理
    private static BaseMessage dealClick(Map<String, String> map) {
        String key=map.get("EventKey");
        String openId=map.get("FromUserName");
        switch (key){
            case "31":
                return new TextMessage(map,"啥也不是");
            case "33":
                return new TextMessage(map,ernie_viLG.clickMenu(openId));
        }
        return null;
    }

    public static String getUserInfo(String openid){
        String url=GET_USER_INFO.replace("ACCESS_TOKEN",AccessTokenTest.getAccessToken()).replace("OPENID",openid);
        return Request.get(url);
    }
}
